package edu.rmit.dao.impl;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;

import edu.rmit.contant.TableConstant;
import edu.rmit.dao.IGroupDAO;
import edu.rmit.domain.Group;
import edu.rmit.domain.User;
import edu.rmit.util.DBManager;

/**
 * This class is to implement the group operation. Like get groups by
 * status, delete group, and change group status function.
 * 
 * @author Thaw Zin
 * @version 1.0
 */
public class GroupDAOImpl implements IGroupDAO {

	/**
	 * The database connection management class.
	 */
	private DBManager dbManager = null;

	/**
	 * The constructor without parameter to initialize a database connection.
	 */
	public GroupDAOImpl() {
		dbManager = new DBManager();
	}

	/**
	 * This method is to implement get groups by status.
	 * 
	 * @param destincationStatus
	 *            The destination status of the group
	 * @return A list of group which the group status is in this status
	 */
	@Override
	public List<Group> getGroupsByStatus(boolean destincationStatus) {
		String sqlString = "select * from " + TableConstant.GROUP_INFO_TABLE
				+ " where isactive = ?";

		Connection connection = dbManager.getConnection();
		PreparedStatement preparedState = null;
		ResultSet rs = null;
		List<Group> groupInfos = new ArrayList<Group>();
		try {
			preparedState = connection.prepareStatement(sqlString);
			preparedState.setBoolean(1, destincationStatus);
			rs = preparedState.executeQuery();
			while (rs.next()) {
				Group groupInfo = new Group();
				groupInfo.setId(rs.getInt("id"));
				groupInfo.setName(rs.getString("name"));
				groupInfo.setDescription(rs.getString("description"));
				groupInfo.setActive(rs.getBoolean("isactive"));
				groupInfo.setCreator(rs.getString("creator"));
				Calendar date = Calendar.getInstance();
				date.setTimeInMillis(rs.getTimestamp("createdate").getTime());
				groupInfo.setCreateDate(date);
				groupInfos.add(groupInfo);
			}
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbManager.closeAll(rs, preparedState, connection);
		}
		return groupInfos;
	}

	/**
	 * This method is to implement add a group to the system.
	 * 
	 * @param currentUser
	 *            The current user who want to add a group
	 * @param name
	 *            The group name which the user want to to add
	 * @param description
	 *            The description of the group.
	 */
	@Override
	public void addGroup(User currentUser, String name, String description) {
		String sqlString = "insert into " + TableConstant.GROUP_INFO_TABLE
				+ "(id,name,description,creator,createdate,isactive)"
				+ " values("+TableConstant.SEQ_GROUP+",?,?,?,?,?)";

		Connection connection = dbManager.getConnection();
		PreparedStatement preparedState = null;
		try {
			preparedState = connection.prepareStatement(sqlString);
			preparedState.setString(1, name);
			preparedState.setString(2, description);
			preparedState.setString(3, currentUser.getUserName());
			preparedState.setTimestamp(4, new Timestamp(new Date().getTime()));
			preparedState.setBoolean(5, false);
			preparedState.executeUpdate();
			
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbManager.closeAll(null, preparedState, connection);
		}
	}

	/**
	 * The method is to delete a group by id.
	 * 
	 * @param groupId
	 *            The group id which a user want to delete.
	 */
	@Override
	public void deleteGroup(int groupId) {
		String deleteMessageSQL = "delete from " + TableConstant.MESSAGE_TABLE
				+ " where groupid = " + groupId;
		String deleteGroupSQL = "delete from " + TableConstant.GROUP_INFO_TABLE
				+ " where id = " + groupId;

		Connection connection = dbManager.getConnection();
		Statement statement = null;

		try {
			statement =  connection.createStatement();
			statement.executeUpdate(deleteMessageSQL);
			statement.executeUpdate(deleteGroupSQL);
		} catch (SQLException e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * This method is to implement change a group status.
	 * 
	 * @param groupId
	 *            The group id which a group want to change.
	 * @param destinationStatus
	 *            The destination status which a current group's status.
	 */
	@Override
	public void changeGroupStatus(int groupId, boolean destinationStatus) {
		String sqlString = "update " + TableConstant.GROUP_INFO_TABLE
		+ " set isactive = ? where id = ?";
		
		Connection connection = dbManager.getConnection();
		PreparedStatement preparedState = null;
		try {
			preparedState = connection.prepareStatement(sqlString);
			//preparedState.execute("begin");
			preparedState.setBoolean(1, destinationStatus);
			preparedState.setInt(2, groupId);
			preparedState.execute();
			//preparedState.execute("commit");
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			dbManager.closeAll(null, preparedState, connection);
		}
	}
}
